/**
 * 修改记录:
 * 25-09-11     郑朝军
 */

/**
 * uni.cxapp.Initialization
 * ZGIS-组件初始化相关方法
 *
 * @class
 * @memberof    uni.cxapp.Initialization
 */
export default
{
  methods:
  {
    /**
     * 初始化组件
     * @returns {Promise<void>}
     */
    async initializeComponent() 
    {
      try 
      {
        this.isLoading = true
        this.loadingMessage = '正在初始化...'
 
        // 初始化cx_datafmt、cx_datavsl、cx_validator
        this.initDataFmtVslValidator()

        // 初始化实体对象
        await this.initializeEntity()

        // 初始化字段列表
        await this.initializeFldList()
       
        // 初始化字段值FldValueMap对象
        await this.initializeFldValueMap()

        // 初始化表单数据（必须在字段列表初始化后）
        await this.initializeFormData()

        // 初始化文件控制器
        this.initializeFileController()

        // 初始化缓存策略
        this.initializeAttMapStrategy()

        // 初始化验证规则
        this.initializeFormRules()

        // 处理默认值
        this.handleDefaultValues()

        // 处理规则表
        this.handleRuleTabOnInit()
      
        // 处理所有字段的params参数 cx_datafmt、cx_datavsl
        this.processFldAllFmtVsl()

        // 生成编码
        this.makeCode()
 
        // 触发就绪回调
        if (this.onReady) 
        {
          this.onReady(this.internalAttMap)
        }
      }
      catch (error) 
      {
        console.error('组件初始化失败:', error)
        this.handleError(error)
      }
      finally 
      {
        this.isLoading = false
      }
    },

    /**
     * 初始化实体对象
     * @returns {Promise<void>}
     */
    async initializeEntity() 
    {
      // 如果没有major和minor，不需要初始化entity
      if (!this.major || !this.minor) 
      {
        console.warn('初始化实体对象失败：缺少必要参数 major 或 minor')
        return
      }

      try 
      {
        // 从数据库查询实体对象
        this.internalEntity = await this.getEntity(this.major, this.minor)
        
        // 如果获取失败，记录警告信息
        if (!this.internalEntity) 
        {
          console.warn(`无法获取实体对象: major=${this.major}, minor=${this.minor}`)
        }
      }
      catch (error) 
      {
        console.error('初始化实体对象失败:', error)
        this.handleError(error)
      }
    },

    /**
     * 初始化字段列表
     * @returns {Promise<void>}
     */
    async initializeFldList() 
    {          
      if (this.fldList && this.fldList.length > 0) 
      {
        this.internalFldList = [...this.fldList]
      } 
      else if (this.internalEntity) 
      {
        // 使用已初始化的entity对象查询字段列表
        const tabName = this.getTabName()              
        if (tabName) 
        {
          this.internalFldList = await this.queryFldList(tabName)          
        }
      }

      // 如果字段列表仍然为空，尝试从TabCfg配置中加载字段
      // 这是一个兜底机制，确保在其他方式都无法获取字段列表时，能从TabCfg配置表中获取基础字段信息   
      if(uni.cxapp.CxValueUtil.isEmptyObj(this.internalFldList) && !this.internalEntity)
      {
        const tabName = this.getTabName()         
        this.loadFromTabCfg(tabName, uni.cxapp.CxConst.tab)
      }
           
      // 处理隐藏和禁用字段
      this.processFieldVisibility()
    },
   
    /**
     * 初始化字段值FldValueMap对象     
     * @returns {Promise<Array>} 字段选项数据数组
     */
    async initializeFldValueMap() 
    {       
      // 参数校验：必须有entity对象才能查询
      if (!this.internalEntity) 
      {
        return
      }

      try 
      {        
        const tabName = this.getTabName()
          
        // 先从缓存中获取当前表的字段选项数据
        let fldValues = await uni.cxapp.fldvalue.queryFldValueListAuto({tabname: tabName, flds: this.internalFldList})
        
        // 如果缓存中有数据，直接返回并设置映射
        if (!uni.cxapp.CxValueUtil.isEmptyObj(fldValues)) 
        {
          // 设置字段值映射，便于后续快速查找
          this.fldValueMap = uni.cxapp.fldvalue.queryTabFldValueListMap(tabName)            
        }
 
        return fldValues
      } 
      catch (error) 
      {
        console.error('查询字段选项数据失败:', error)
        this.handleError(error)

        return []
      }        
    },

    /**
     * 初始化文件控制器
     */
    initializeFileController() 
    {
      this.internalFileController = this.fileHandler
        ? this.fileHandler
        : this.hasMediaComponents ? this.createDefaultFileController()
        : undefined      
    },

    /**
     * 初始化默认缓存策略实例
     */
    initializeAttMapStrategy() 
    {
      if (this.attMapStrategy) 
      {
        this.internalAttMapStrategy = this.attMapStrategy
      }
      else
      {
        this.internalAttMapStrategy = this.createDefaultAttMapStrategy()
      } 
    },

    /**
     * 初始化表单数据
     */
    async initializeFormData() 
    {     
      if (!this.internalAttMap || Object.keys(this.internalAttMap).length === 0) 
      {
        this.internalAttMap = {}
      }
    
      // 为所有字段初始化默认值
      this.initializeFieldValues()     
    },

    /**
     * 检查传入的对象 internalAttMap 是否只包含 id 字段，
     * 如果条件成立，则调用 queryById 方法查询。
     *
     * @param {Object} internalAttMap - 属性映射对象，期望包含 id 字段。
     * @returns {Promise<void>} 异步方法，无返回值。
     */
    async checkAndQueryById(internalAttMap) 
    {
      if (internalAttMap.id && Object.keys(internalAttMap).length === 1) 
      {             
        await this.queryById(internalAttMap.id)
      }
    },

    /**
     * 为所有字段初始化默认值
     * 参考旧版本 form.js 中的 initFieldsData 方法
     */
    initializeFieldValues() 
    {   
      // 确保 internalFldList 已初始化
      if (!this.internalFldList || this.internalFldList.length === 0) 
      {
        return
      }
      
      // 为每个字段设置默认值      
      this.internalFldList.forEach(fld => 
      {      
        // 如果字段值不存在，设置默认值
        if (!(fld.colname in this.internalAttMap)) 
        {
          // 优先使用已有的值，其次使用字段默认值，最后使用空字符串
          let defaultValue = this.internalAttMap[fld.colname] ?? ''      
          // 如果是新增模式且字段有默认值
          if (this.isAddMode() && fld.defval) 
          {           
            defaultValue = uni.cxapp.fld.parseDefval(fld.defval)
          }
      
          // 设置字段值          
          this.internalAttMap[fld.colname] = defaultValue
        }

        // 设置ExpEngine需要用到的信息
        fld.rows = (fld.params?.rows ?? 0) || fld.disprows
        fld.type = fld.disptype
        fld.title = fld.namec        
      })
     
      // 确保 internalAttMap 是响应式的
      this.internalAttMap = { ...this.internalAttMap }
    },

    /**
     * 初始化表单验证规则
     */
    initializeFormRules() 
    {
      const rules = {}
  
      for (const fld of this.internalFldList) 
      {
        const fieldRules = []

        // 必填验证 - 只在提交时验证，不在输入时验证
        if (fld.nullable === 0) 
        {
          fieldRules.push(
          {
            required: true,
            message: `${fld.namec}不能为空`,
            trigger: 'submit'  // 改为只在提交时触发
          })
        }

        // fld.param字段自定义验证规则
        const validator = this.getFldValidator(fld)
        if (validator) 
        {
          fieldRules.push(validator)
        }

        if (fieldRules.length > 0) 
        {
          rules[fld.colname] = fieldRules
        } 
      }
    
      this.formRules = rules
    },

    /**
     * 处理默认值（包括缓存数据）
     */
    handleDefaultValues() 
    {
      if (!this.isAddMode()) 
      {
        return
      }

      // 获取缓存数据
      const cacheData = this.isCache ? this.attMapStrategyHandler.getCacheData() : {}
    
      // 处理缓存数据，覆盖默认值
      for (const fld of this.internalFldList) 
      {    
        if (cacheData[fld.colname]) 
        {
          this.internalAttMap[fld.colname] = cacheData[fld.colname]       
        }
      }

      // 确保响应式更新
      this.internalAttMap = { ...this.internalAttMap }       
    },
     
    /**
     * 处理规则表初始化
     */
    handleRuleTabOnInit() 
    {
      // 1、取规则数据      
      this.ruleTabList = uni.cxapp.CxArrayUtil.gets(uni.cxapp.InitSvrMethod.getRuleTab(), {tab: this.getTabName()})
   
      // 2、初始化规则数据
      if (this.isAddMode()) 
      {
        this.handleRuleTab(this.ruleTabCheckTime.new)
      }
      else if (this.isEditMode()) 
      {
        this.handleRuleTab(this.ruleTabCheckTime.edit)
      }
    },
    
    /**
     * 初始化cx_datafmt、cx_datavsl、cx_validator 1、fld数据格式化配置 2、表单字段的颜色 3、配置验证规则用
     * @method
     */
    initDataFmtVslValidator() 
    {
      // 初始化新特性数据
      uni.cxapp.Datafmt.init(uni.cxapp.InitSvrMethod.getDatafmt())
      uni.cxapp.DataVsl.init(uni.cxapp.InitSvrMethod.getDatavsl())
      uni.cxapp.Validator.init(uni.cxapp.InitSvrMethod.getValidator())      
    },

    /**
     * 生成编码
     */
    makeCode() 
    {
      if (!this.isViewMode() && this.hasCodeField()) 
      {
        // 实现编码生成逻辑
        console.log('生成编码')
      }
    },

    /**
     * 检查是否有编码字段
     * @returns {boolean} 是否有编码字段
     */
    hasCodeField() 
    {
      return this.internalFldList.some(fld => fld.colname === 'code')
    }
  }
}
